package com.mlx.meng.author;

import com.mlx.meng.tool.DataPermissionException;
import com.mlx.meng.tool.DataPermissionUtil;
import com.mlx.meng.verify.DataPermissionColumnVerification;
import com.mlx.meng.tool.DataPermissionProperties;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 列数据权限授权器
 * 功能：1、提供获取当前用户所有列数据权限的接口
 *      2、生成列数据权限验证器
 * @param <T>
 */
public abstract class AbstractDataPermissionColumnAuthorization<T> extends WhiteListCollector {

    @Autowired
    private DataPermissionProperties properties;

    protected abstract Collection<T> getColumnPermissions();

    public DataPermissionColumnVerification getTableColumnPermissions() throws Exception{
        DataPermissionColumnVerification columnVerification = new DataPermissionColumnVerification();
        Collection<T> objectCollection = getColumnPermissions();
        if (objectCollection == null || objectCollection.isEmpty()){
            return columnVerification;
        }
        Iterator<T> iterator = objectCollection.iterator();
        Object next = iterator.next();
        Class<?> aClass = next.getClass();
        Field tableNameField = aClass.getDeclaredField(properties.getTableName());
        Field fieldNameField = aClass.getDeclaredField(properties.getFieldName());


        tableNameField.setAccessible(true);
        fieldNameField.setAccessible(true);

        for (T obj : objectCollection){

            String tableName = tableNameField.get(obj).toString();
            String fieldName = fieldNameField.get(obj).toString();

            columnVerification.put(tableName, fieldName);
        }

        return columnVerification;
    }

    public void dataFilter(Collection<?> dataCollection, String tableName, String[] foreignKeys) throws Exception{

        if (DataPermissionUtil.isEmpty(dataCollection)){
            return;
        }

        if (isInWhiteList()){
            return;
        }

        DataPermissionColumnVerification columnVerification = getTableColumnPermissions();
        DataPermissionColumnVerification.DataPermissionColumnEntityVerification entityVerification = columnVerification.buildDataPermissionColumnEntity(tableName, foreignKeys);

        // 没有数据权限就没有数据
        if (entityVerification.isNotExistDataPermission()){
            dataCollection.clear();
            return;
        }

        // 获取数据类型
        Iterator<?> iterator1 = dataCollection.iterator();
        Object next = iterator1.next();
        Class<?> aClass = next.getClass();

        // 获取数据类型的属性集合
        Map<String, Field> fieldMap = DataPermissionUtil.gainClassField(aClass);
        // 获取所有的权限字段
        Set<String> permissionField = entityVerification.getEntityColumnPermission();
        // 检查数据类型是否拥有对应权限字段的属性
        for (String k : permissionField){
            if (!(fieldMap.containsKey(k))){
                throw new DataPermissionException("返回数据的数据类型不存在权限字段【%s】指定的属性", k);
            }
        }

        // 过滤数据
        dataCollection.forEach(data -> {
            try {
                entityVerification.columnPermissionFilter(data, fieldMap);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        });
    }

    public void dataFilter(Collection<?> dataCollection, String tableName, String[] foreignKeys, String setMethodName, Class<?> fieldType, Class<?> valueType, int fieldTypeIndex, String getAllFieldMethodName) throws Exception{

        if (DataPermissionUtil.isEmpty(dataCollection)){
            return;
        }

        if (isInWhiteList()){
            return;
        }

        DataPermissionColumnVerification columnVerification = getTableColumnPermissions();
        DataPermissionColumnVerification.DataPermissionColumnEntityVerification entityVerification = columnVerification.buildDataPermissionColumnEntity(tableName, foreignKeys);

        // 没有数据权限就没有数据
        if (entityVerification.isNotExistDataPermission()){
            dataCollection.clear();
            return;
        }

        // 获取数据类型
        Iterator<?> iterator1 = dataCollection.iterator();
        Object next = iterator1.next();
        Class<?> aClass = next.getClass();

        // 获取setMethodName指定的属性值获取方法
        Method setMethod = fieldTypeIndex == 0 ? aClass.getDeclaredMethod(setMethodName, fieldType, valueType) : aClass.getDeclaredMethod(setMethodName, valueType, fieldType);

        Method getAllFieldMethod = aClass.getDeclaredMethod(getAllFieldMethodName);

        Class<?> returnType = getAllFieldMethod.getReturnType();

        if (!(Collection.class.isAssignableFrom(returnType))){
            throw new DataPermissionException("getAllFieldMethodName方法返回类型不是Collection类型");
        }


        dataCollection.forEach(data -> {
            try {
                entityVerification.columnPermissionFilter(data, setMethod, fieldTypeIndex, getAllFieldMethod);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        });
    }

}
